﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GOFconsole
{
    public class Chapter26_Flyweight
    {
        public void FlyweightTest()
        { 
            //Model
            int extrinsicstate = 22;    //代码外部状态 extrinsic:外部的
            FlyweightFactory f = new FlyweightFactory();

            Flyweight fx = f.GetFlyweight("X");
            fx.Operation(--extrinsicstate);
            Flyweight fy = f.GetFlyweight("Y");
            fy.Operation(--extrinsicstate);
            Flyweight fz = f.GetFlyweight("Z");
            fz.Operation(--extrinsicstate);

            UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
            uf.Operation(--extrinsicstate);

            //.NET中享元模式的运用
            string t1 = "AAAAA";
            string t2 = "AAAAA";
            Console.WriteLine(Object.ReferenceEquals(t1,t2));//TRUE,说明t1,t2是相同的实例

            //Demo(网站共享)
            WebsiteFactory wf = new WebsiteFactory();

            Website wfx = wf.GetWebsiteCategory("产品展示");
            wfx.Use(new User_C26("小菜"));

            Website wfy = wf.GetWebsiteCategory("产品展示");
            wfy.Use(new User_C26("大鸟"));

            Website wfz = wf.GetWebsiteCategory("产品展示");
            wfz.Use(new User_C26("老顽童"));

            Website wfn = wf.GetWebsiteCategory("博客");
            wfn.Use(new User_C26("用户A"));

            Website wfm = wf.GetWebsiteCategory("博客");
            wfm.Use(new User_C26("用户B"));

            Console.WriteLine("网站的分类总数为:"+wf.GetWebsiteCount());
        }

    }

    #region Model
    //所有具体共享类的超类或接口，通过这个接口，Flyweight可以接受并作用于外部状态
    abstract class Flyweight
    {
        public abstract void Operation(int extrinsicstate);
    }
    //继承或实现Flyweight，并为内部状态增加存储空间
    class ConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("具体Flyweight:"+extrinsicstate);
        }
    }
    //UnsharedConcreteFlyweight是指那些不需要共享的Flyweight子类
    class UnsharedConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
        }
    }
    //FlyweightFactory，享元工厂，用来创建并管理Flyweight对象。用来确保合理的共享Flyweight，当用户请求
    //一个Flyweight时，FlyweightFactory对象提供一个已创建的实例或者创建一个。
    class FlyweightFactory
    {
        private Hashtable flyweights = new Hashtable();

        public FlyweightFactory()   //初始化工厂时先生成3个实例
        {
            flyweights.Add("X",new ConcreteFlyweight());
            flyweights.Add("Y", new ConcreteFlyweight());
            flyweights.Add("Z", new ConcreteFlyweight());
        }

        public Flyweight GetFlyweight(string key)
        { 
            return ((Flyweight)flyweights[key]);
        }
    }

    #endregion

    #region DEMO(共享网站)
    public class User_C26   //用户类，网站的账号
    {
        private string name;
        public User_C26(string name)
        {
            this.name = name;
        }
        public string Name
        {
            get { return name; }
        }
    }

    abstract class Website  //网站抽象类
    {
        public abstract void Use(User_C26 user);
    }

    class ConcreteWebsite : Website
    {
        private string name = "";
        public ConcreteWebsite(string name)
        {
            this.name = name;
        }

        public override void Use(User_C26 user)
        {
            Console.WriteLine("网站分类:" + name + " 用户:" + user.Name);
        }
    }

    class WebsiteFactory
    {
        private Hashtable flyweights = new Hashtable();
        
        //获得网站分类
        public Website GetWebsiteCategory(string key)
        {
            if (!flyweights.ContainsKey(key))
            {
                flyweights.Add(key, new ConcreteWebsite(key));
            }
            return (Website)flyweights[key];
        }

        //获得网站分类总数
        public int GetWebsiteCount()
        {
            return flyweights.Count;
        }

    }


    #endregion

}
